package com.ddtech.business.course.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ddtech.business.common.BaseService;
import com.ddtech.business.constant.BusinessEnum;
import com.ddtech.business.constant.Del;
import com.ddtech.business.course.entity.Course;
import com.ddtech.business.course.entity.CourseChapter;
import com.ddtech.business.course.mapper.CourseChapterMapper;
import com.ddtech.business.course.query.ChapterQuery;
import com.ddtech.business.course.service.CourseChapterService;
import com.ddtech.business.course.service.CourseResourceService;
import com.ddtech.business.course.vo.CourseVo;
import com.ddtech.business.course.vo.res.CourseChapterTreeVo;
import com.ddtech.exception.BizPreconditions;
import com.ddtech.utils.TreeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 章节表 服务实现类
 * </p>
 *
 * @author bin_pu
 * @since 2023-02-06
 */
@Service
class CourseChapterServiceImpl extends BaseService<CourseChapterMapper, CourseChapter> implements CourseChapterService {

    @Autowired
    private CourseResourceService courseResourceService;

    @Override
    public void create(CourseChapter courseChapter) {
        courseChapter.init();
        this.saveOrUpdate(courseChapter);
    }

    @Override
    public void del(String id) {
        CourseChapter courseChapter = this.getById(id);
        BizPreconditions.check(courseChapter == null, BusinessEnum.QUERY_ERROR.getMsg());
        List<String> ids = new ArrayList<>();
        ids.add(courseChapter.getId());
        Set<CourseChapter> courseChapterSet = new HashSet<>();
        findSubType(ids, courseChapterSet);
        courseChapterSet.forEach(item -> {
            item.baseDelete();
            this.saveOrUpdate(item);
        });
    }

    @Override
    public Object getTree(ChapterQuery chapterQuery) {
        List<CourseChapter> courseTypeList = this.list(chapterQuery.autoWrapper());
        List<CourseChapterTreeVo> data = courseTypeList.stream().map(map -> JSON.parseObject(JSON.toJSONString(map), CourseChapterTreeVo.class))
                .sorted(Comparator.comparing(CourseChapterTreeVo::getSort, Comparator.nullsFirst(Comparator.naturalOrder())))
                .collect(Collectors.toList());
        return TreeUtils.buildListToTree(data);
    }

    @Override
    public void saveChapter(Course course, CourseVo courseVo) {
        LambdaQueryWrapper<CourseChapter> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseChapter::getCourseId, course.getId());
        List<CourseChapter> courseChapterList = this.list(queryWrapper);
        List<CourseChapter> courseChapters = courseVo.getCourseChapter();
        //courseChapterList-courseChapters
        List<CourseChapter> collect = courseChapterList.stream().filter(item -> !courseChapters.contains(item)).collect(Collectors.toList());
        for (CourseChapter courseChapter : collect) {
            courseChapter.baseDelete();
            courseResourceService.removeResource(courseChapter);
            this.saveOrUpdate(courseChapter);
        }
        courseChapters.forEach(chapter -> {
            chapter.setCourseId(course.getId());
            chapter.init();
            this.saveOrUpdate(chapter);
            courseResourceService.saveResource(chapter);
        });

    }

    @Override
    public List<CourseChapter> getChapter(String courseId) {
        LambdaQueryWrapper<CourseChapter> queryWrapper = Wrappers.<CourseChapter>lambdaQuery()
                .eq(CourseChapter::getCourseId, courseId)
                .eq(CourseChapter::getIsDelete, Del.FALSE.getStatus())
                .orderByAsc(CourseChapter::getSort);
        List<CourseChapter> list = this.list(queryWrapper);
        list.forEach(chapter -> {
            chapter.setCourseResourceList(courseResourceService.getResource(chapter.getId()));
        });
        return list;
    }

    @Override
    public List<CourseChapter> getChapterList(String courseId) {
        LambdaQueryWrapper<CourseChapter> queryWrapper = Wrappers.<CourseChapter>lambdaQuery()
                .eq(CourseChapter::getCourseId, courseId)
                .eq(CourseChapter::getIsDelete, Del.FALSE.getStatus())
                .orderByAsc(CourseChapter::getSort);
        List<CourseChapter> list = this.list(queryWrapper);
        list.forEach(chapter -> {
            chapter.setCourseResourceList(courseResourceService.getResourceList(chapter.getId()));
        });
        return list;
    }

    public void findSubType(List<String> ids, Set<CourseChapter> courseChapterSet) {
        for (String id : ids) {
            ChapterQuery chapterQuery = new ChapterQuery();
            chapterQuery.setPid(id);
            List<CourseChapter> list = this.list(chapterQuery.autoWrapper());
            if (CollUtil.isNotEmpty(list)) {
                List<String> collect = list.stream().map(CourseChapter::getId).collect(Collectors.toList());
                findSubType(collect, courseChapterSet);
            }
            courseChapterSet.add(this.getById(id));
        }
    }
}
